/*
 * Copyright 2013 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.util;

/**
 * 计算引用(reference-counted)的对象, 需要显示的释放.
 * <p>
 *
 * <ul>
 *     <li>初始实例化, 引用计数为 {@code 1}</li>
 *     <li>{@link #retain()} 增加引用计数</li>
 *     <li>{@link #release()} 减少引用计数</li>
 *     <li>{@code 0}: 对象将被显式地释放. 访问已释放对象通常会导致访问冲突(access violation)</li>
 * </ul>
 * 如果一个实现 {@link ReferenceCounted} 的对象是其它实现 {@link ReferenceCounted} 对象的容器, 那么当容器的引用计数为 0 时,
 * 其包含的对象也将被释放(通过 {@link #release()}).
 */
public interface ReferenceCounted {
    /**
     * 返回该对象的引用计数
     * 如果为 {@code 0}, 这意味着该对象已经被释放
     */
    int refCnt();

    /**
     * 引用计数 + {@code 1}
     */
    ReferenceCounted retain();

    /**
     * 引用计数 + 指定 {@code increment}
     */
    ReferenceCounted retain(int increment);

    /**
     * Records the current access location of this object for debugging purposes.
     * If this object is determined to be leaked, the information recorded by this operation will be provided to you
     * via {@link ResourceLeakDetector}.  This method is a shortcut to {@link #touch(Object) touch(null)}.
     */
    ReferenceCounted touch();

    /**
     * Records the current access location of this object with an additional arbitrary information for debugging
     * purposes.  If this object is determined to be leaked, the information recorded by this operation will be
     * provided to you via {@link ResourceLeakDetector}.
     */
    ReferenceCounted touch(Object hint);

    /**
     * 引用计数 - {@code 1}, 如果结果为 {@code 0}, 那么该对象将被回收.
     *
     * @return {@code true}: 当且仅当该对象的引用计数变为 {@code 0}, 并且该对应已经被释放
     */
    boolean release();

    /**
     * 引用计数 - {@code decrement}, 如果结果为 {@code 0}, 那么该对象将被回收.
     *
     * @return 当且仅当该对象的引用计数变为 {@code 0}, 并且该对应已经被释放
     */
    boolean release(int decrement);
}
